home *** CD-ROM | disk | FTP | other *** search
- /* ConnectTheDots -----------------------------------------
- *
- * Response to Jan 94 MacTech Programmer's Challenge.
- *
- * Object:
- * Go around QD to draw color lines as fast as possible.
- *
- * Specs:
- * nDots >= 2,
- * handle only cases {(pixelSize,cmpSize,cmpCount) =
- * (8,8,1), (16,5,3), (32,8,3)},
- * arbitrary alpha-bits,
- * don't bother clipping,
- * penSize = 1,1,
- * patCopy mode.
- *
- * Notes on method:
- * Specify segment by two endpoints {(x,y)=(a,b),(A,B)}.
- * Form of line is {(x,y): (y-b)/(x-a) = m}, where slope
- * m = (B-b)/(A-a). Then, y = m*(x-a)+b.
- *
- * Two successive values of y are:
- * y2 = m*(x2-a)+b; y1 = m*(x1-a)+b, and the diff is,
- * y2-y1 = m, since x2-x1 will always = 1 (pixel).
- *
- * Therefore, as we move from x to x, we add or sub
- * m to the previous value of y.
- *
- * Speed:
- * The cases that arise for combinations of {dy,dx}
- * fall generally into 8 octants that cover the plane.
- * Diagonally opposite octants are treated together,
- * so there are 4 main cases to worry about. We first
- * weed out 3 special cases: exactly horizontal,
- * vertical, and diagonal segs. These are the simplest,
- * most common, and fastest.
- *
- * In a given octant, one of |dx|, |dy| is strictly
- * larger than the other. Our loop over pixels will
- * always be over the larger magnitude for higher
- * resolution drawing. The slope is formed then by
- * smallNum/largeNum which must have quotient == 0,
- * and remainder == smallNum. Adding the slope is
- * a matter of accumulating remainders. If this sum
- * exceeds largeNum, we move to next pixel.
- *
- * billKarsh
- */
-
- #pragma options( honor_register, !assign_registers )
- #pragma options( !check_ptrs )
-
- #include "ConnectTheDots.h"
-
- #define HiFiveMask 0xF800
- #define Abs( a ) (a > 0 ? a : -a)
-
- /* RGB2Index ----------------------------------------------
- *
- * Expects rgb color is an exact member of table, to
- * avoid time spent close matching. Index is just
- * position in table.
- */
- static Byte RGB2Index(
- ColorSpec *cSpec,
- RGBColor *rgb )
- {
- register ColorSpec *cs = cSpec;
- register short entries = ((short*)cs)[-1]+1;
- register short red = rgb->red,
- green = rgb->green,
- blue = rgb->blue;
-
- do {
- if( red == cs->rgb.red &&
- blue == cs->rgb.blue &&
- green == cs->rgb.green )
- return cs-cSpec;
-
- ++cs;
- } while( --entries );
- }
-
- /* Lines8 -------------------------------------------------
- *
- * Depth == 8 case.
- *
- * To maximize register usage, chose to put rowBytes
- * in address reg. Also, some vars like v_Cnt are
- * dual purpose.
- */
- static void Lines8(
- PixMapPtr pm,
- Point dot[],
- unsigned short nDots,
- register Byte pixel )
- {
- register Ptr at;
- #include "ConnectTheDots.com"
- }
-
- /* Lines16 ------------------------------------------------
- */
- static void Lines16(
- PixMapPtr pm,
- Point dot[],
- unsigned short nDots,
- register short pixel )
- {
- register short *at;
- #include "ConnectTheDots.com"
- }
-
- /* Lines32 ------------------------------------------------
- *
- * align ensures 4-byte stack alignment for better speed.
- */
- static void Lines32(
- PixMapPtr pm,
- Point dot[],
- unsigned short nDots,
- short align,
- register long pixel )
- {
- register long *at;
- #include "ConnectTheDots.com"
- }
-
- /* ConnectTheDots -----------------------------------------
- */
- void ConnectTheDots(
- unsigned short nDots,
- Point dot[],
- PixMapHandle pmH,
- RGBColor color )
- {
- register PixMapPtr pm = *pmH;
- register unsigned short pix16;
- register Ptr p32;
- long pix32;
-
- if( pm->pixelSize == 8 ) {
-
- Lines8( pm, dot, nDots,
- RGB2Index(&(**pm->pmTable).ctTable, &color) );
- }
- if( pm->pixelSize == 16 ) {
-
- pix16 = (color.red & HiFiveMask) >> 1;
- pix16 |= (color.green & HiFiveMask) >> 6;
- pix16 |= (color.blue & HiFiveMask) >> 11;
-
- Lines16( pm, dot, nDots, pix16 );
- }
- if( pm->pixelSize == 32 ) {
-
- p32 = ((Byte*)&pix32) + 1;
- *p32++ = *(Byte*)&color.red;
- *p32++ = *(Byte*)&color.green;
- *p32++ = *(Byte*)&color.blue;
-
- Lines32( pm, dot, nDots, 0, pix32 );
- }
- }
-